home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Compendium Deluxe 2
/
LSD and 17bit Compendium Deluxe - Volume II.iso
/
a
/
prog
/
asmsrc
/
thesource-7.lha
/
Source
/
DefFunc.lha
/
DefFunc
/
dfctree.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-14
|
4KB
|
200 lines
/*********************************************************
*
* Copyright (c) 1993 Ke Jin
*
* Permission to use, copy, modify, and distribute
* this software and its documentation without fee
* is granted, provided that the author's name and
* this copyright notice are retained.
*
* -----------------------------------------------------
*
* dfctree.c -- defunc low level module
*
* public function : exparse();
* evaluate();
* reduce();
*
*********************************************************/
#include <stdio.h>
#include "dfctree.h"
#ifdef __cplusplus
extern "C" { /* for c++ */
#endif
#if NeedFunctionPrototypes
extern yyinit(char* expression);
extern int yyparse(void);
#else
extern yyinit();
extern int yyparse();
#endif
#define ltree reduce(tree+tree->left-i, tree->left)
#define rtree reduce(tree+tree->right-i, tree->right)
#define trval tree->content.value
#define ltrval ltree->content.value
#define rtrval rtree->content.value
#if NeedFunctionPrototypes
Node* reduce(Node* tree, int i)
#else
Node* reduce(tree, i)
Node* tree;
int i;
#endif
/* constant folding. i is the shift relative to root
* reduce tree still in original memory address. the
* root of the tree be returned */
{
if(tree == 0) return 0;
switch(tree->type)
{
case const_node:
case arg_node:
break;
case simplex_fnct_node:
if(rtree->type==const_node)
{
tree->type = const_node;
trval = (tree->content.fnctptr)(rtrval);
}
break;
case duplex_fnct_node:
if((ltree->type==const_node)&&(rtree->type==const_node))
{
tree->type = const_node;
trval = (tree->content.fnctptr)(ltrval, rtrval);
}
break;
case unary_op_node:
if(rtree->type==const_node)
{
tree->type = const_node;
switch(tree->content.op)
{
case op_neg: trval = -rtrval; break;
default: break;
}
}
break;
case binary_op_node:
if(rtree->type==const_node&&tree->content.op==op_div)
{
tree->content.op=op_mul;
rtree->content.value = 1.0/(rtree->content.value);
}
if(ltree->type==const_node&&rtree->type==const_node)
{
tree->type = const_node;
switch(tree->content.op)
{
case op_sum: trval = ltrval+rtrval; break;
case op_sub: trval = ltrval-rtrval; break;
case op_mul: trval = ltrval*rtrval; break;
case op_div: trval = ltrval/rtrval; break;
default: break;
}
}
break;
default: break;
}
return tree;
};
#if NeedFunctionPrototype
int exparse(char* expression)
#else
int exparse(expression)
char* expression;
#endif
{
yyinit(expression); /* initial the parser */
return yyparse(); /* on success, return 0 or tree size
* on error , return -1 */
};
#define lval evaluate(tree+tree->left-i, tree->left , x, y)
#define rval evaluate(tree+tree->right-i, tree->right, x, y)
#if NeedFunctionPrototype
double evaluate(Node* tree, int i, double x, double y)
#else
double evaluate(tree, i, x, y)
Node* tree;
int i;
double x, y;
#endif
/* evaluate a parse tree. i is the shift relative to root */
{
if(tree == 0)
{
fprintf(stderr, "Null parse tree\n");
exit(1) ;
}
switch (tree->type)
{
case const_node:
return tree->content.value;
case arg_node:
switch(tree->content.argidx)
{
case 1: return x;
case 2: return y;
default: exit(1);
}
break;
case simplex_fnct_node:
return (tree->content.fnctptr)(rval);
case duplex_fnct_node:
return (tree->content.fnctptr)(lval, rval);
case unary_op_node:
switch(tree->content.op)
{
case op_neg: return -rval;
default: break;
}
break;
case binary_op_node:
switch(tree->content.op)
{
case op_sum: return lval + rval;
case op_sub: return lval - rval;
case op_mul: return lval * rval;
case op_div: return lval / rval;
default: break;
}
break;
default:
exit(1) ; /* something wrong */
}
return 0; /* turn off the warning of lint */
};
#ifdef __cplusplus
} /* end for c++ */
#endif